package com.jboltai.event.ai.aifunccall;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.jboltai.capability.functioncall.FuncCallResult;
import com.jboltai.capability.message.AIMessageRole;
import com.jboltai.event.CompleteHandler;
import com.jboltai.event.EventType;
import com.jboltai.event.FailHandler;
import com.jboltai.event.SuccessHandler;
import com.jboltai.event.ai.aitext.AITextEvent;
import com.jboltai.event.handler.AIFuncCallEventHandler;
import com.jboltai.resource.ai.AIModel;
import com.jboltai.resource.functioncall.FunctionCallProvider;
import com.jboltai.resource.functioncall.FunctionResource;
import com.jboltai.resource.functioncall.FunctionResourceCenter;
import com.jboltai.resource.functioncall.GroupFunctionCallProvider;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * ai事件
 */
public class AIFuncCallEvent extends AITextEvent<AIFuncCallEvent, FuncCallResult, AIFuncCallEventHandler> {

    private static final double DEFAULT_TEMPERATURE = 0.1D;


    public AIFuncCallEvent() {
        super(EventType.AI_FUNC_CALL);
        setTemperature(DEFAULT_TEMPERATURE);
    }

    public AIFuncCallEvent(AIModel model) {
        super(EventType.AI_FUNC_CALL);
        setTemperature(DEFAULT_TEMPERATURE);
        this.aiChatEvent.setModel(model);
    }


    /**
     * 创建一个ai事件
     * @param model 使用哪个模型，具体的模型名称根据该枚举值的defaultModel获取
     * @param successHandler
     * @param failHandler
     */
    public AIFuncCallEvent(AIModel model, SuccessHandler<AIFuncCallEvent, FuncCallResult> successHandler, FailHandler failHandler) {
        super(EventType.AI_FUNC_CALL);
        setTemperature(DEFAULT_TEMPERATURE);
        this.aiChatEvent.setModel(model);
        this.successHandler = successHandler;
        this.failHandler = failHandler;
    }
    /**
     * 创建一个ai事件
     * @param model 使用哪个模型，具体的模型名称根据该枚举值的defaultModel获取
     * @param successHandler
     * @param failHandler
     */
    public AIFuncCallEvent(AIModel model, SuccessHandler<AIFuncCallEvent, FuncCallResult> successHandler, FailHandler failHandler, CompleteHandler completeHandler) {
        super(EventType.AI_FUNC_CALL);
        setTemperature(DEFAULT_TEMPERATURE);
        this.aiChatEvent.setModel(model);
        this.successHandler = successHandler;
        this.failHandler = failHandler;
        this.completeHandler = completeHandler;
    }




    /**
     * 使用的function资源
     */
    private HashSet<String> functionResourceIds;


    @Override
    public String preCheck() {
        if (StrUtil.isBlank(this.oriPrompt) &&
                (this.aiChatEvent == null || this.aiChatEvent.getContextMessages().isEmpty() || this.aiChatEvent.getContextMessages().stream().noneMatch(item -> item.getRole() == AIMessageRole.user))) {
            return "未设置用户消息";
        }
        if (this.functionResourceIds == null || this.functionResourceIds.isEmpty()) {
            return "未设置function清单";
        }
        return null;
    }

    /**
     * 根据id绑定function资源
     * @param functionIds
     * @return
     */
    public AIFuncCallEvent bindFunctionResourceByIds(String... functionIds) {
        if (functionIds == null) {
            throw new IllegalArgumentException("functionIds不能为空");
        }
        if (this.functionResourceIds == null) {
            this.functionResourceIds = new HashSet<>();
        }
        for (String id : functionIds) {
            this.functionResourceIds.add(id);
        }

        return this;
    }

    /**
     * 根据id绑定function资源
     * @param functionIds
     * @return
     */
    public AIFuncCallEvent bindFunctionResourceByIds(String[] functionIds, FunctionCallProvider provider) {
        if (functionIds == null) {
            throw new IllegalArgumentException("functionIds不能为空");
        }
        if (this.functionResourceIds == null) {
            this.functionResourceIds = new HashSet<>();
        }
        List<String> notExistResources = null;
        for (String id : functionIds) {
            if (FunctionResourceCenter.checkExist(id)) {
                this.functionResourceIds.add(id);
            } else {
                if (notExistResources == null) {
                    notExistResources = new ArrayList<>();
                }
                notExistResources.add(id);
            }
        }
        if (notExistResources != null) {
            FunctionResource resource;
            for(String id:notExistResources){
                resource = provider.provide(id);
                if (resource != null) {
                    FunctionResourceCenter.registerIfNotExist(resource);
                    this.functionResourceIds.add(id);
                }
            }
        }
        return this;
    }


    /**
     * 绑定 整个组的function资源
     * @param functionGroupIds
     * @return
     */
    public AIFuncCallEvent bindFunctionResourceByGroups(String... functionGroupIds) {
        if (functionGroupIds == null) {
            throw new IllegalArgumentException("functionGroupIds不能为空");
        }
        if (this.functionResourceIds == null) {
            this.functionResourceIds = new HashSet<>();
        }
        for (String groupId : functionGroupIds) {
            List<String> ids = FunctionResourceCenter.getResourceIdsByGroup(groupId);
            if (ids != null) {
                this.functionResourceIds.addAll(ids);
            }
        }
        return this;
    }

    /**
     * 绑定 整个组的function资源
     * @param functionGroupIds
     * @return
     */
    public AIFuncCallEvent bindFunctionResourceByGroups(String[] functionGroupIds, GroupFunctionCallProvider provider) {
        if (functionGroupIds == null) {
            throw new IllegalArgumentException("functionGroupIds不能为空");
        }
        if (this.functionResourceIds == null) {
            this.functionResourceIds = new HashSet<>();
        }
        List<String> notExistGroups = null;
        for (String groupId : functionGroupIds) {
            if (FunctionResourceCenter.checkGroupExist(groupId)) {
                List<String> ids = FunctionResourceCenter.getResourceIdsByGroup(groupId);
                if (ids != null) {
                    this.functionResourceIds.addAll(ids);
                }
            } else {
                if (notExistGroups == null) {
                    notExistGroups = new ArrayList<>();
                }
                notExistGroups.add(groupId);
            }
        }
        if (notExistGroups != null) {
            List<FunctionResource> resources;
            for(String groupId : notExistGroups){
                resources = provider.provide(groupId);
                if (resources != null && !resources.isEmpty()) {
                    for (FunctionResource resource : resources) {
                        FunctionResourceCenter.registerIfNotExist(groupId, resource);
                        this.functionResourceIds.add(resource.getId());
                    }
                }
            }

        }
        return this;
    }


    /**
     * 获取function资源的ids
     * @return
     */
    public HashSet<String> getFunctionResourceIds() {
        return functionResourceIds;
    }

    /**
     * 获取function资源的json字符串
     * @return
     */
    public String getFunctionResourceJSON() {
        if (functionResourceIds == null) return null;

        return JSON.toJSONString(functionResourceIds.stream().map(FunctionResourceCenter::getById).filter(Objects::nonNull)
                .map(FunctionResource::toJSONObject).collect(Collectors.toList()), SerializerFeature.WriteMapNullValue);
    }


}
